package org.example.yuaiagent.controller;

import jakarta.annotation.Resource;
import org.example.yuaiagent.agent.YuManus;
import org.example.yuaiagent.app.TravelApp;
import org.example.yuaiagent.chatmemory.MysqlChatMemory;
import org.example.yuaiagent.constant.SysConstant;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/ai")
public class AiController {
    @Resource
    private TravelApp travelApp;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 同步调用 ai
     */
    @GetMapping("/travel_app/chat")
    public String doChatWithTravelAppBySync(String message, String chatId)
    {
        return travelApp.doChat(message, chatId);
    }

    /**
     * sse 流式调用 ai
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value="/travel_app/chat/sse",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> doChat(String message, String chatId,String token)
    {
        if (token == null ||token.isEmpty()) {
            return Flux.just("请先登录");
        }
        String u =stringRedisTemplate.opsForValue().get(SysConstant.loing_user_key + token);
        if (u == null || u.isEmpty()) {
            return Flux.just("请先登录");
        }
        if (message == null ||message.isEmpty()||chatId  == null ||chatId.isEmpty()) {
            return null;
        }
        return travelApp.doChatByStream(message, chatId);
    }

    /**
     * sse 流式调用 ai
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/travel_app/chat/server_sent_event")
    public Flux<ServerSentEvent<String>> doChatWithLoveAppServerSentEvent(String message, String chatId) {
        return travelApp.doChatByStream(message, chatId)
                .map(chunk -> ServerSentEvent.<String>builder()
                        .data(chunk)
                        .build());
    }

    /**
     * SSE 流式调用 AI 恋爱大师应用
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/travel_app/chat/sse_emitter")
    public SseEmitter doChatWithLoveAppServerSseEmitter(String message, String chatId) {
        // 创建一个超时时间较长的 SseEmitter
        SseEmitter sseEmitter = new SseEmitter(180000L); // 3 分钟超时
        // 获取 Flux 响应式数据流并且直接通过订阅推送给 SseEmitter
        travelApp.doChatByStream(message, chatId)
                .subscribe(chunk -> {
                    try {
                        sseEmitter.send(chunk);
                    } catch (IOException e) {
                        sseEmitter.completeWithError(e);
                    }
                }, sseEmitter::completeWithError, sseEmitter::complete);
        // 返回
        return sseEmitter;
    }


    @Resource
    private ToolCallback[] allTools;

    @Resource
    private ChatModel dashscopeChatModel;

    @Autowired
    private MysqlChatMemory mysqlChatMemory;


    Map<String, YuManus> yuManusMap= new HashMap<>();


    /**
     * 流式调用 Manus 超级智能体
     *
     * @param message
     * @return
     */
    @GetMapping("/manus/chat")
    public SseEmitter doChatWithManus(String message,String chatId,String token) {
        if (token == null) {
            return null;
        }
        String s = stringRedisTemplate.opsForValue().get(SysConstant.loing_user_key + token);
        if (s == null) {
            return null;
        }
        // 参数校验
        if (message == null ||message.isEmpty()||chatId  == null ||chatId.isEmpty()) {
            return null;
        }
        boolean b = yuManusMap.containsKey(chatId);
        if (!b) {
            YuManus yuManus = new YuManus(allTools, toolCallbackProvider, dashscopeChatModel,mysqlChatMemory);
            // 考虑持久化
            List<Message> messageList=new ArrayList<>();
            yuManus.setChatId(chatId);
            yuManus.setMessageList(messageList);
            yuManusMap.put(chatId, yuManus);
        };
        YuManus yuManus = yuManusMap.get(chatId);
        return yuManus.runStream(message);
    }


    @Resource
    private ToolCallbackProvider toolCallbackProvider;
///**
// * 使用已弃用用的类有风险
// */
//    public List<FunctionCallback> allToolsAndMcpTool() {
//        ArrayList<FunctionCallback> toolCallbacks = new ArrayList<>();
//        toolCallbacks.addAll(List.of(allTools));
//        toolCallbacks.addAll(List.of(toolCallbackProvider.getToolCallbacks()));
//        return toolCallbacks;
//    }
}